package com.servicelive.service;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.servicelivedb.ServiceliveDB;
import com.servicelivedb.data.Block;
import com.servicelivedb.data.Customer;
import com.servicelivedb.data.CustomerProject;
import com.servicelivedb.data.Door;
import com.servicelivedb.data.Project;
import com.wavemaker.runtime.RuntimeAccess;
import com.wavemaker.runtime.javaservice.JavaServiceSuperClass;
import com.wavemaker.runtime.service.annotations.ExposeToClient;

@ExposeToClient
public class ServiceLiveService extends JavaServiceSuperClass {
	public ServiceLiveService() {
		super(INFO);
	}

	public UserDetails retrieveUserDetails(String email, String password) {

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");
		UserDetails result = new UserDetails();
		try {

			db.begin();

			Session session = db.getDataServiceManager().getSession();

			Query query = session
					.createQuery(" from Customer user where user.email= :email and user.password= :password ");
			query.setString("email", email);
			query.setString("password", password);
			List userList = query.list();

			if (userList != null && !userList.isEmpty()) {

				Customer user = (Customer) userList.get(0);
				System.out.println("$$$$$$$$ user found ::" + user.getName());
				result.setCustomerId(user.getCustomerId());
				result.setEmail(user.getEmail());
				result.setAuthenticated(true);
				result.setName(user.getName());
				result.setRoles(user.getType());
				result.setMessage("User Logged in successfully");

				for (CustomerProject cp : user.getCustomerProjects()) {
					if (cp.getProject().getActive()) {
						result.setProjectId(cp.getProject().getProjectId());
					}
				}

			} else {
				System.out.println("User not found ");
				result.setMessage("User Not Found");
				result.setAuthenticated(false);

			}

			log(INFO, "Returning " + result);

			db.commit();
		} catch (Exception e) {
			db.rollback();
			System.out.println(e.getMessage());
			result.setMessage("User Not Found");
			result.setAuthenticated(false);
			log(ERROR, "Error in retrieveUserDetails;user=" + email
					+ ";password=" + password, e);
		}
		return result;

	}

	public String register(Customer customer, String activationCode)
			throws Exception {
		String result = null;

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");

		try {

			db.begin();

			Session session = db.getDataServiceManager().getSession();
			// TODO: validations
			Criteria criteria = session.createCriteria(Customer.class);
			criteria.add(Restrictions.eq("email", customer.getEmail()));
			List results = criteria.list();
			if (results != null && !results.isEmpty()) {

				throw new Exception(
						"Email id already in use.Please use different id or login using the same");
			}

			Query query = session
					.createQuery(" from Project project where project.projectId= :projectId ");
			query.setInteger("projectId", Integer.parseInt(activationCode));
			Project project = (Project) query.uniqueResult();

			customer.setUpdatedBy("SYS");
			customer.setUpdatedDt(new Date());
			customer.setActive(true);
			customer.setType("CUSTOMER");
			session.save(customer);

			CustomerProject cp = new CustomerProject();
			cp.setActive(true);
			cp.setCustomer(customer);
			cp.setProject(project);
			// cp.setBlock(customer.getBlock());
			// cp.setDoorNo(customer.getDoor());

			session.save(cp);

			log(INFO, "Starting sample operation");

			System.out.println("activationCode::" + activationCode);
			System.out.println("customer::" + customer.getName());

			log(INFO, "Returning " + result);

			db.commit();
			result = "User registration successfull";
		} catch (Exception e) {
			db.rollback();
			log(ERROR, "Error during registration", e);
			throw e;
		}
		return result;
	}

	public String registerVendor(Customer customer, String activationCode,
			Boolean isVendor) throws Exception {
		String result = null;

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");

		try {

			db.begin();

			Session session = db.getDataServiceManager().getSession();
			// TODO: validations
			Criteria criteria = session.createCriteria(Customer.class);
			criteria.add(Restrictions.eq("email", customer.getEmail()));
			List results = criteria.list();
			if (results != null && !results.isEmpty()) {

				throw new Exception(
						"Email id already in use.Please use different id or login using the same");
			}

			Query query = session
					.createQuery(" from Project project where project.projectId= :projectId ");
			query.setInteger("projectId", Integer.parseInt(activationCode));
			Project project = (Project) query.uniqueResult();

			customer.setUpdatedBy("SYS");
			customer.setUpdatedDt(new Date());
			customer.setActive(true);
			if (isVendor)
				customer.setType("VENDOR");
			else
				customer.setType("CUSTOMER");
			customer.setProject(project);

			Block block = (Block) session.get(Block.class, customer.getBlock()
					.getBlockId());
			customer.setBlock(block);

			Door door = (Door) session.get(Door.class, customer.getDoor()
					.getDoorId());
			customer.setDoor(door);

			session.save(customer);

			CustomerProject cp = new CustomerProject();
			cp.setActive(true);
			cp.setCustomer(customer);
			cp.setProject(project);

			// cp.setBlock(customer.getBlock());
			// cp.setDoorNo(customer.getDoor());

			session.save(cp);

			log(INFO, "Starting sample operation");

			System.out.println("activationCode::" + activationCode);
			System.out.println("customer::" + customer.getName());

			result = "Hello World";
			log(INFO, "Returning " + result);

			db.commit();
		} catch (Exception e) {
			db.rollback();
			log(ERROR, "The sample java service operation has failed", e);
			throw e;
		}
		return result;
	}

	public class UserDetails {

		private Integer customerId;
		private String name;
		private boolean isAuthenticated;
		private String roles;
		private String message;
		private String email;
		private Integer projectId;
		private String type;

		public Integer getProjectId() {
			return projectId;
		}

		public void setProjectId(Integer projectId) {
			this.projectId = projectId;
		}

		public Integer getCustomerId() {
			return customerId;
		}

		public void setCustomerId(Integer customerId) {
			this.customerId = customerId;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public boolean isAuthenticated() {
			return isAuthenticated;
		}

		public void setAuthenticated(boolean isAuthenticated) {
			this.isAuthenticated = isAuthenticated;
		}

		public String getRoles() {
			return roles;
		}

		public void setRoles(String roles) {
			this.roles = roles;
		}

		public String getEmail() {
			return email;
		}

		public void setEmail(String email) {
			this.email = email;
		}

		public String getMessage() {
			return message;
		}

		public void setMessage(String message) {
			this.message = message;
		}

		public String getType() {
			return type;
		}

		public void setType(String type) {
			this.type = type;
		}

	}
}
